use std::collections::HashSet;
use crate::db::dao::im_label_dao::{label_inserts, label_total, label_updates, query_labels_by_names};
use crate::db::db::Db;
use crate::db::db_transaction::transaction;
use crate::db::pojo::pojo::ImLabel;

pub struct ImLabelService;

impl ImLabelService {

    pub fn save_labels(&self, user_id: String, labels: &mut Vec<ImLabel>) {
        let db = Db::open();
        let user_id_clone = user_id.clone();
        transaction(db.clone(), move |db: Db| {
            self.save_labels_business(db, user_id_clone, labels)
        });
    }

    pub fn total(&self)->usize {
        let db = Db::open();
        let total = transaction(db.clone(), move |db: Db| {
            label_total(db)
        });
        total
    }

    fn save_labels_business(&self, db: Db, user_id: String,  labels: &mut Vec<ImLabel>) {
        let names = labels.iter().map(|c| c.name.as_str()).collect::<Vec<&str>>();
        let db_labels = query_labels_by_names(db.clone(), &user_id, names);

        let db_names = db_labels.iter().map(|label| label.name.as_str()).collect::<HashSet<&str>>();
        let mut insert_labels= Vec::new();
        let mut update_labels = Vec::new();

        for label in labels {
            let name = label.name.as_str();
            if !db_names.contains(name) {
                insert_labels.push(label);
            } else {
                update_labels.push(label);
            }
        }

        label_inserts(db.clone(), &mut insert_labels);
        label_updates(db.clone(), &mut update_labels);
    }

}